<template>
  <div id="image-manager-container" v-if="hasPerm('image_cd')">
    <el-card class="box-card" style="width: 600px">
      <div style="display: flex; justify-content: center; margin-bottom: 10px">
        <el-text class="mx-1" type="primary" style="margin-right: 10px">选择数据集:</el-text>
        <el-cascader v-model="category" :props="selectorProps" placeholder="请选择" />
      </div>
      <el-upload
        :show-file-list="false"
        class="upload-demo"
        drag
        multiple
        :auto-upload="false"
        ref="uploadRef"
        :accept="upload_accept"
        :on-change="handleChange"
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          拖动图片到这里
          <em>{{ buttonText }}</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            <el-text class="mx-1" type="primary" size="large">可上传多个图片,当前图片数量:</el-text>
            <el-text class="mx-1" type="success" size="large">{{ fileList.length }}</el-text>
          </div>
        </template>
      </el-upload>
      <el-input v-model="description" :rows="1" type="textarea" placeholder="请输入图片描述" style="margin-bottom: 10px;"/>
      <div style="display: flex; justify-content: center">
        <el-button type="primary" :icon="Refresh" size="small" @click="removeFiles" />
        <el-button
          type="primary"
          round
          :icon="Upload"
          size="small"
          style="margin-left: 10px"
          @click="verify"
          :loading="isLoading"
        >
          点击上传
        </el-button>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts" setup>
import { getParentCategoriesApi, getSubCategoriesApi } from "@/api/data-manager/categoryApi"
import { CascaderProps, ElMessage, UploadInstance } from "element-plus"
import { ref, computed } from "vue"
import { Upload, Refresh } from "@element-plus/icons-vue"
import { openConfirmBox } from "@/utils/confirmBox.ts"
import { uploadImageApi } from "@/api/data-manager/imageApi"
import { useLoginStore } from "@/store/loginStore"

const loginStore = useLoginStore()

function hasPerm(perm: string) : boolean {
    return loginStore.perms.includes(perm)
}

const buttonText = computed(() => {
  return isLoading.value ? "正在上传，请稍后" : "点击上传"
})
const isLoading = ref<boolean>(false)

const uploadRef = ref<UploadInstance>()
const upload_accept = ref(".jpg,.png,.jpeg,.tiff,.psd,.raw,.eps,.svg")
const fileList = ref<any[]>([])
const fileNameSet = ref<Set<string>>(new Set<string>())
const description = ref<string>()

function handleChange(file: any) {
  if (!fileNameSet.value.has(file.name)) {
    fileList.value.push(file)
    fileNameSet.value.add(file.name)
    uploadRef.value?.clearFiles()
  }
}

function removeFiles() {
  fileList.value = []
  fileNameSet.value.clear()
  description.value = ''
}

function verify() {
  if (!category.value) {
    ElMessage.warning("请选择数据集")
    return
  }
  if (fileList.value.length === 0) {
    ElMessage.warning("请选择上产图片")
    return
  }
  if (!(description.value && description.value !== '')) {
    ElMessage.warning("请输入图片描述")
    return
  }
  openConfirmBox("确认上传吗？", submitFiles)
}

function submitFiles() {
  setTimeout(async () => {
    isLoading.value = true
    const data = new FormData()
    fileList.value.forEach((file) => {
      data.append("image", file.raw)
    })
    let res
    try {
      res = await uploadImageApi(category.value[0], category.value[1], description.value!, data)
    } catch (error) {
      ElMessage.error("上传失败，请稍后再试")
      return
    }
    ElMessage.success("上传成功")
    removeFiles()
    isLoading.value = false
  })
}

const category = ref()
const selectorProps: CascaderProps = {
  expandTrigger: "hover" as const,
  lazy: true,
  lazyLoad(node, resolve) {
    const { level } = node
    setTimeout(async () => {
      if (level === 0) {
        const parentCategories = await getParentCategories()
        resolve(
          parentCategories.map((data) => ({
            value: data.id,
            label: data.name,
            leaf: false
          }))
        )
      } else {
        const childDataSets = await getChildrenCategories(<number>node.value)
        resolve(
          childDataSets.map((data) => ({
            value: data.id,
            label: data.name,
            leaf: true
          }))
        )
      }
    })
  }
}

async function getParentCategories(): Promise<any[]> {
  let res
  try {
    res = await getParentCategoriesApi()
  } catch (error) {
    ElMessage.error("获取大类别列表失败")
    return []
  }
  return res.data
}

async function getChildrenCategories(id: number): Promise<any[]> {
  let res
  try {
    res = await getSubCategoriesApi(String(id))
  } catch (error) {
    ElMessage.error("获取数据集列表失败")
    return []
  }
  return res.data
}
</script>

<style lang="scss" scoped>
#image-manager-container {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  :deep(.el-upload-dragger) {
    border: 2px #a6a9ad dashed;
    border-radius: 10px;
  }
  :deep(.el-upload-dragger:hover) {
    border: 2px #66b1ff dashed;
    border-radius: 10px;
  }
}
</style>
